package com.lin.sqltool.controller;

import com.lin.sqltool.common.BaseQueryController;
import com.lin.sqltool.config.IconConfig;
import com.lin.sqltool.factory.ConnectionServiceFactory;
import com.lin.sqltool.model.ConnectionInfoModel;
import com.lin.sqltool.model.FieldInfoModel;
import com.lin.sqltool.model.IndexInfoModel;
import com.lin.sqltool.service.ConnectionService;
import com.lin.sqltool.utils.IconUtil;
import javafx.application.Platform;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.*;
import javafx.scene.image.ImageView;
import javafx.scene.input.InputMethodEvent;
import javafx.scene.input.MouseButton;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.*;

public class ConnectionTabController {

    private static final Logger log = LoggerFactory.getLogger(ConnectionTabController.class);
    /**
     * 连接树信息
     */
    @FXML
    private TreeView<String> databaseTreeView;

    @FXML
    private TabPane queryTabPane;
    /**
     * 表信息
     */
    @FXML
    private TableView<FieldInfoModel> tableInfoTable;

    /**
     * 索引信息
     */
    @FXML
    private TableView<IndexInfoModel> indexInfoTable;

    /**
     * ddl信息
     */
    @FXML
    private TextArea ddlTextArea;

    //每个tab使用的连接信息
    private ConnectionInfoModel connectionInfo;

    //连接使用的服务
    private ConnectionService connectionService;

    /**
     * 上一个打开的tab
     */
    private Tab previousTab;


    // 用于缓存已加载的数据库表信息
    private final Map<String, List<String>> databaseCache = new LinkedHashMap<>();

    private final Map<Tab, BaseQueryController> connectionTabMap = new HashMap<>();

    public void setConnectionInfo(ConnectionInfoModel connectionInfo) {
        this.connectionInfo = connectionInfo;
        this.connectionService = ConnectionServiceFactory.getService(connectionInfo.getDatabaseType());

        queryTabPane.getSelectionModel().selectedItemProperty().addListener((obs, oldTab, newTab) -> {
            if (newTab != null) {
                previousTab = oldTab;
            }
        });

        addAddTab();    //添加(index总会在最后)

        addAIQueryTab();    //ai

        addCommonQueryTab();    //普通

        addQueryLogTab();   //日志

        initializeTreeView();   //树结构

        queryTabPane.getSelectionModel().select(0);
    }

    private void initializeTreeView() {
        loadDatabases();
    }

    /**
     * 加载数据库
     */
    private void loadDatabases() {
        // 创建根节点
        String rootName = connectionInfo.getName() + " : " + connectionInfo.getHost();
        TreeItem<String> rootItem = new TreeItem<>(rootName);
        rootItem.setExpanded(true);
        // 加载数据库列表
        List<String> databases = connectionService.getDatabases(connectionInfo);
        databases.forEach(db -> {
            TreeItem<String> dbItem = new TreeItem<>(db);
            ImageView icon = IconUtil.createIcon(IconConfig.DATABASE_ICON, 10, 10);
            dbItem.setGraphic(icon);
            rootItem.getChildren().add(dbItem);
        });

        databaseTreeView.setRoot(rootItem);



        ContextMenu contextMenu = new ContextMenu();    //右键菜单
        databaseTreeView.setOnContextMenuRequested(event -> {
            TreeItem<String> selectedItem = databaseTreeView.getSelectionModel().getSelectedItem();
            if (selectedItem == null) return;

            // 判断节点类型
            if (selectedItem.getParent() == rootItem) {
                // 库节点：显示库的菜单项
                buildDatabaseContextMenu(contextMenu, selectedItem);
            } else if (selectedItem.getParent().getParent() == rootItem) {
                // 表节点：显示表的菜单项
                buildTableContextMenu(contextMenu, selectedItem);
            }

            contextMenu.show(databaseTreeView, event.getScreenX(), event.getScreenY());
            event.consume();
        });




        // 鼠标事件处理
        databaseTreeView.setOnMouseClicked(event -> {
            // 先判断是否为左键
            if (event.getButton() != MouseButton.PRIMARY) return;

            if (contextMenu.isShowing()) {  //如果菜单显示就把菜单隐藏
                contextMenu.hide();
            }

            TreeItem<String> selectedItem = databaseTreeView.getSelectionModel().getSelectedItem();
            if (event.getClickCount() == 2) {
                if (selectedItem != null && !selectedItem.equals(rootItem) && selectedItem.getParent().equals(rootItem)) {   //选中的不是根节点且选中的父级是跟节点
                    if (selectedItem.getChildren().isEmpty()) {
                        this.loadTables(selectedItem);
                    }
                    selectedItem.setExpanded(true);

                    //设置选中的数据库
                    connectionTabMap.forEach((key, value) -> {
                        if (value != null) {
                            value.setDatabaseInfo(selectedItem.getValue());
                        }
                    });

                }
            }
            if (event.getClickCount() == 1) {
                if (selectedItem != null && !selectedItem.equals(rootItem) && !selectedItem.getParent().equals(rootItem)) {   //选中的不是根节点且选中的父级也不是根节点 (说明是表)

                    String databaseName = selectedItem.getParent().getValue();
                    String tableName = selectedItem.getValue();

                    Platform.runLater(() -> {
                        // 显示表信息
                        showTableInfo(databaseName, tableName);

                        // 显示索引信息
                        showIndexInfo(databaseName, tableName);

                        // 显示 DDL
                        showTableDDL(databaseName, tableName);

                        // 显示前200条数据
                        showTableData(databaseName, tableName);
                    });

                }
            }

        });
    }

    private void buildDatabaseContextMenu(ContextMenu menu, TreeItem<String> dbItem) {
        menu.getItems().clear();
        MenuItem refreshDb = new MenuItem("刷新数据库");
        refreshDb.setOnAction(e -> {

        });


        MenuItem deleteDb = new MenuItem("删除数据库");
        deleteDb.setOnAction(e -> {

        });

        MenuItem addTable = new MenuItem("添加数据表");
        addTable.setOnAction(e -> {

        });


        menu.getItems().addAll(refreshDb, deleteDb, addTable);
    }

    private void buildTableContextMenu(ContextMenu menu, TreeItem<String> tableItem) {
        menu.getItems().clear();
        MenuItem refreshTable = new MenuItem("修改表结构");
        refreshTable.setOnAction(e -> {

        });

        MenuItem viewData = new MenuItem("查看表数据");
        viewData.setOnAction(e -> {

        });

        MenuItem deleteData = new MenuItem("删除数据表");
        deleteData.setOnAction(e -> {

        });

        menu.getItems().addAll(refreshTable, viewData, deleteData);
    }


    /**
     * 加载数据表哦
     *
     * @param selectedItem
     */
    private void loadTables(TreeItem<String> selectedItem) {
        List<String> tables = databaseCache.get(selectedItem.getValue());
        if (tables == null || tables.isEmpty()) {
            tables = connectionService.getTables(connectionInfo, selectedItem.getValue());
            databaseCache.put(selectedItem.getValue(), tables);
            for (String table : tables) {
                TreeItem<String> tableItem = new TreeItem<>(table);
                ImageView icon = IconUtil.createIcon(IconConfig.TABLE_ICON, 15, 15);
                tableItem.setGraphic(icon);
                selectedItem.getChildren().add(tableItem);
            }
        }
    }

    /**
     * 显示表信息
     *
     * @param database
     * @param table
     */
    private void showTableInfo(String database, String table) {
        try {
            List<FieldInfoModel> columns = connectionService.getTableColumns(connectionInfo, database, table);

            // 清除旧列
            tableInfoTable.getColumns().clear();

            // 创建列并使用Lambda设置值工厂
            TableColumn<FieldInfoModel, String> nameColumn = new TableColumn<>("字段");
            nameColumn.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getName()));

            TableColumn<FieldInfoModel, String> typeColumn = new TableColumn<>("类型");
            typeColumn.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getType()));

            TableColumn<FieldInfoModel, String> commentColumn = new TableColumn<>("注释");
            commentColumn.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getComment()));

            tableInfoTable.getColumns().addAll(nameColumn, typeColumn, commentColumn);
            tableInfoTable.setPlaceholder(new Label("无字段信息数据"));
            tableInfoTable.setItems(FXCollections.observableArrayList(columns));

        } catch (Exception e) {
            log.error("加载表格字段失败", e);
            tableInfoTable.setPlaceholder(new Label("加载失败: " + e.getMessage()));
        }
    }

    /**
     * 显示索引信息
     *
     * @param database
     * @param table
     */
    private void showIndexInfo(String database, String table) {
        try {
            List<IndexInfoModel> indexes = connectionService.getTableIndexes(connectionInfo, database, table);
            // 清除旧列
            indexInfoTable.getColumns().clear();

            // 创建列并使用Lambda设置值工厂
            TableColumn<IndexInfoModel, String> nameColumn = new TableColumn<>("名称");
            nameColumn.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getName()));

            TableColumn<IndexInfoModel, String> typeColumn = new TableColumn<>("类型");
            typeColumn.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getType()));

            TableColumn<IndexInfoModel, String> commentColumn = new TableColumn<>("字段");
            commentColumn.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().getFields()));

            indexInfoTable.getColumns().addAll(nameColumn, typeColumn, commentColumn);
            indexInfoTable.setPlaceholder(new Label("无索引信息数据"));
            indexInfoTable.setItems(FXCollections.observableArrayList(indexes));
        } catch (Exception e) {
            log.error(e.getMessage());
        }
    }

    /**
     * 显示ddl信息
     *
     * @param database
     * @param table
     */
    private void showTableDDL(String database, String table) {
        try {
            String ddl = connectionService.getTableDDL(connectionInfo, database, table);
            ddlTextArea.setEditable(false);
            ddlTextArea.setText(ddl);
        } catch (Exception e) {
            log.error(e.getMessage());
        }
    }





    /**
     * 添加常用 sql tab
     */
    private void addCommonQueryTab() {
        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/CommonSQLEditorTabView.fxml"));
            Tab tabContent = loader.load();
            CommonQueryController controller = loader.getController();
            controller.setConnectionInfo(connectionInfo); //传递连接信息
            connectionTabMap.put(tabContent, controller);
            queryTabPane.getTabs().add(queryTabPane.getTabs().size() - 1,tabContent);
            queryTabPane.getSelectionModel().select(tabContent);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 添加ai sql tab
     */
    private void addAIQueryTab() {
        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/AISQLEditorTabView.fxml"));
            Tab tabContent = loader.load();
            AIQueryController controller = loader.getController();
            controller.setConnectionInfo(connectionInfo); //传递连接信息
            controller.handleAddTextCall();
            System.out.println("controller_info : " + controller);
            connectionTabMap.put(tabContent, controller);
            queryTabPane.getTabs().add(queryTabPane.getTabs().size() - 1, tabContent);
            queryTabPane.getSelectionModel().select(tabContent);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 添加查询日志
     */
    private void addQueryLogTab() {
        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/EditorLogTabView.fxml"));
            Tab tabContent = loader.load();
            queryTabPane.getTabs().add(queryTabPane.getTabs().size() - 1,tabContent);
            queryTabPane.getSelectionModel().select(tabContent);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 添加窗口
     */
    private void addAddTab() {
        Tab addTab = new Tab();
        addTab.setClosable(false);
        addTab.setText(" + ");
        addTab.setOnSelectionChanged(event -> {
            if (queryTabPane.getTabs().size() > 1 && addTab.isSelected()) {
                // 创建选择器
                queryTabPane.getSelectionModel().select(previousTab);
                ChoiceDialog<String> dialog = new ChoiceDialog<>("ai查询器",
                        FXCollections.observableArrayList(
                                "ai查询器",
                                "SQL查询器",
                                "历史记录"
                        ));
                dialog.setTitle("提示");
                dialog.setHeaderText("请选择一个要新增查询");
                dialog.setContentText("选择页面:");
                // 显示选择器并获取用户选择
                Optional<String> result = dialog.showAndWait();
                result.ifPresent(selectedTab -> {
                    if (selectedTab.equals("ai查询器")) {
                        addAIQueryTab();
                    } else if (selectedTab.equals("SQL查询器")) {
                        addCommonQueryTab();
                    } else if (selectedTab.equals("历史记录")) {
                        addQueryLogTab();
                    }
                });
            }
        });
        queryTabPane.getTabs().add(addTab);
    }

    /**
     * 显示表格数据
     *
     * @param databaseName
     * @param tableName
     */
    private void showTableData(String databaseName, String tableName) {
        String sql = "select * from " + databaseName + "." + tableName + " limit 200";
        for (Tab tab : this.queryTabPane.getTabs()) {
            if (tab.isSelected()) {
                if (connectionTabMap.get(tab) != null) {
                    connectionTabMap.get(tab).runSQL(sql);
                }

                break;
            }
        }
    }


    /**
     * 过滤
     *
     * @param inputMethodEvent
     */
    public void handleFilter(InputMethodEvent inputMethodEvent) {

    }
}
